package com.utils.parsetxt.property;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Locale;
import java.util.Properties;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 注意：在使用中遇到的最大的问题可能是配置文件的路径问题，
 * 如果配置文件入在当前类所在的包下，那么需要使用包名限定，如：test.properties
 * 入在com.mmq包下，则要使用com/mmq/test.properties（通过Properties来获取）
 * 或com/mmq/test（通过ResourceBundle来获取）；
 * 属性文件在src根目录下，则直接使用test.properties或test即可。
 * @author XR-8
 *
 */
@SuppressWarnings({ "resource", "unused" })
public class PropertyUtil {
    private static final Logger logger = LoggerFactory.getLogger(PropertyUtil.class);
    private static Properties props;
    private static ResourceBundle rb;
	static {
		loadProperties();
	}
	
	//常用一五 \二四,假设文件在src/config/config.properties
	private synchronized static void loadProperties() {
		logger.info("开始加载properties文件");
		props = new Properties();
		InputStream in = null;
		try {
			/**
			 * 一、通过jdk提供的java.util.Properties类。
			 */
//			<!--第一种，通过当前类加载器进行获取properties文件流-->
//			config/config.properties 位于src目录下
			in = PropertyUtil.class.getClassLoader().getResourceAsStream("config/config.properties");
			
//			<!--第二种，通过类进行获取properties文件流-->
//			读取和PropertyUtil类同一个包内的配置文件
			in = PropertyUtil.class.getResourceAsStream("test.properties");
			
//			<!--第三种，通过类加载器进行获取properties文件流,和第一种一样--->
			in = ClassLoader.getSystemResourceAsStream("config/config.properties");
			
//			<!--第四种，通过FileInputStream获取properties文件流-->
			in = new FileInputStream(new File("config/config.properties"));
			
//			<!--第五种，通过BufferedInputStream获取properties文件流-->
			in = new BufferedInputStream(new FileInputStream("src/config/config.properties"));
			
//			<!--第六种，通过URL获取properties文件流-->
			URL url = new URL("path");  
			InputStream inStream = url.openStream(); 
			
//			<!--第七种，Servlet中可以使用javax.servlet.ServletContext的getResourceAsStream()方法获取properties文件流-->
//			in = context.getResourceAsStream("filePath");
			 
			props.load(in);
			
			
			/**
			 * 二、通过java.util.ResourceBundle类来读取，这种方式比使用Properties要方便一些。
			 */
//			<!--第八种，通过ResourceBundle.getBundle()静态方法-->
			rb = ResourceBundle.getBundle("filePath", Locale.getDefault());
//			<!--第九种，从InputStream中读取-->
			in = new BufferedInputStream(new FileInputStream("filePath"));
			rb = new PropertyResourceBundle(in);

		} catch (FileNotFoundException e) {
			logger.error("文件未找到");
		} catch (IOException e) {
			logger.error("IOException");
		}finally {
			try {
				in.close();
			} catch (IOException e) {
				logger.error("文件流关闭异常");
			}
		}
		
		logger.info("结束加载peoperties文件");
	}
	
	public static String getProperty(String key) {
		if(props == null) {
			loadProperties();
		}
		
		//Properties
		String value = props.getProperty(key);
		
		//ResourceBundle
		value = rb.getString(key);
		
		return value;
	}
	
	public static Object getProperty(String key, String defaultValue) {
		if(props == null) {
			loadProperties();
		}
        return props.getProperty(key, defaultValue);
	}

	// 写入Properties信息
	public static void WriteProperties(String filePath, String pKey, String pValue) throws IOException {
		Properties pps = new Properties();

		InputStream in = new FileInputStream(filePath);
		// 从输入流中读取属性列表（键和元素对）
		pps.load(in);
		// 调用 Hashtable 的方法 put。使用 getProperty 方法提供并行性。
		// 强制要求为属性的键和值使用字符串。返回值是 Hashtable 调用 put 的结果。
		OutputStream out = new FileOutputStream(filePath);
		pps.setProperty(pKey, pValue);
		// 以适合使用 load 方法加载到 Properties 表中的格式，
		// 将此 Properties 表中的属性列表（键和元素对）写入输出流
		pps.store(out, "Update " + pKey + " name");
	}
	
}
